package top.wyloop.intoeins.module.ledger.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import top.wyloop.intoeins.exception.SystemException;
import top.wyloop.intoeins.module.ledger.model.consts.InitAccountConst;
import top.wyloop.intoeins.module.ledger.model.entity.Account;
import top.wyloop.intoeins.module.ledger.repository.AccountRepository;
import top.wyloop.intoeins.module.ledger.repository.JournalRepository;
import top.wyloop.intoeins.module.ledger.service.AccountService;
import top.wyloop.intoeins.util.PrimaryKeyGenerator;

import java.util.List;
import java.util.Optional;

/**
 * @author Wyatt6
 * @date 2025/3/28
 */
@Slf4j
@Service
public class AccountServiceImpl implements AccountService {
    @Autowired
    private AccountRepository accountRepository;
    @Autowired
    private JournalRepository journalRepository;

    @Override
    public Account createAccount(Long userId, Account account) {
        log.info("[[创建新记账账户]]");
        Assert.notNull(userId, "用户ID为空");
        Assert.notNull(account, "新记账账户数据为空");
        log.info("输入参数: userId=[{}], account=[{}]", userId, account);

        if (account.getName() != null && InitAccountConst.AUTO_GEN_NAME.equals(account.getName().trim())) {
            log.info("不能与自动生成的{}记账账户重复", InitAccountConst.AUTO_GEN_NAME);
            throw new SystemException("无法新增名为“" + account.getName().trim() + "”的记账账户");
        }

        if (account.getName() != null && !InitAccountConst.AUTO_GEN_NAME.equals(account.getName().trim())) {
            log.info("准备插入的记账账户名为: {}，需要先判断是否已存在", account.getName());
            Optional<Account> c = accountRepository.findByUserIdAndName(userId, account.getName().trim());
            if (c.isPresent()) {
                throw new SystemException("记账账户“" + account.getName().trim() + "”已存在");
            }
        }

        log.info("插入记录");
        account.setId(null);
        account.setUserId(userId);
        if (account.getActivated() == null) account.setActivated(false);
        account.setSortId(new PrimaryKeyGenerator().next());
        account = accountRepository.save(account);
        log.info("成功插入记录: id=[{}]", account.getId());
        return account;
    }

    @Override
    public void deleteAccount(Long userId, Long accountId) {
        log.info("[[删除记账账户]]");
        Assert.notNull(userId, "用户ID为空");
        Assert.notNull(accountId, "记账账户ID为空");
        log.info("输入参数: userId=[{}], accountId=[{}]", userId, accountId);

        // 自动生成的<默认虚拟记账账户>记账账户不支持
        Optional<Account> account = accountRepository.findByUserIdAndName(userId, InitAccountConst.AUTO_GEN_NAME);
        if (account.isPresent() && account.get().getId().equals(accountId)) {
            throw new SystemException("此记账账户无法删除");
        }

        log.info("将相关联的记账明细的动账渠道字段设为{}或null", InitAccountConst.AUTO_GEN_NAME);
        journalRepository.setAccountIdByUserIdAndAccountId(userId, accountId, account.isPresent() ? account.get().getId() : null);
        // TODO 删除记账账户时对外键关联的数据记录的处理

        log.info("删除记账账户记录");
        accountRepository.deleteByIdAndUserId(accountId, userId);
    }

    @Override
    public Account updateAccount(Long userId, Account account) {
        log.info("[[更新记账账户]]");
        Assert.notNull(userId, "用户ID为空");
        Assert.notNull(account, "新记账账户数据为空");
        Assert.notNull(account.getId(), "新记账账户ID为空");
        log.info("输入参数: userId=[{}], account=[{}]", userId, account);

        log.info("查询是否存在该记账账户");
        Optional<Account> oldAccount = accountRepository.findByIdAndUserId(account.getId(), userId);
        if (oldAccount.isPresent()) {
            // 自动生成的<默认虚拟记账账户>记账账户不支持
            if (InitAccountConst.AUTO_GEN_NAME.equals(oldAccount.get().getName().trim())) {
                throw new SystemException("此记账账户无法更新");
            }

            String name = account.getName();
            Boolean activated = account.getActivated();
            Long sortId = account.getSortId();

            log.info("记账账户存在，组装用来更新的对象");
            Account newAccount = oldAccount.get();
            if (name != null) newAccount.setName(name);
            if (activated != null) newAccount.setActivated(activated);
            if (sortId != null) newAccount.setSortId(sortId);

            log.info("更新数据库记录");
            newAccount = accountRepository.save(newAccount);

            return newAccount;
        } else {
            throw new SystemException("记账账户不存在");
        }
    }

    @Override
    public List<Account> getAccounts(Long userId) {
        log.info("[[查询用户的所有记账账户]]");
        Assert.notNull(userId, "用户ID为空");
        log.info("输入参数: userId=[{}]", userId);

        Sort sort = Sort.by("sortId");
        List<Account> accounts = accountRepository.findByUserId(userId, sort);
        log.info("查询结果: {}", accounts);

        return accounts;
    }

    @Override
    public Account findAccountById(Long userId, Long accountId) {
        log.info("[[根据ID查找记账账户]]");
        Assert.notNull(userId, "用户ID为空");
        Assert.notNull(accountId, "记账账户ID为空");
        log.info("输入参数: userId=[{}], accountId=[{}]", userId, accountId);

        return accountRepository.findByIdAndUserId(accountId, userId).orElse(null);
    }
}
